import { FieldTypeMappingEnum } from '@model/enum/FieldMappingEnum';
import DateFormatEnum from '@model/enum/DateFormatEnum';
/* model */
import { ConnectorBizTypeEnum, ConnectorBizTypeIdEnum, ConnectorConditionTypeEnum, ConnectorEditOptions, ConnectorFromField, ConnectorField, ConnectorFieldEnNameEnum, ConnectorFieldTypeEnum, ConnectorOptions, ConnectorOptionsFieldOption, ConnectorToField, ConnectorOptionsFieldOptionValueTypeEnum, ConnectorFieldTypeChildrenMap } from '@src/modules/connector/model'
import { parse } from '@src/util/lang/object'
import Log from '@src/util/log'
import { isFalsy, isNotArray, isObject } from '@src/util/type'
import Field from '@src/model/Field'
import { t } from '@src/locales'
import { formatDate, useFormTimezone } from 'pub-bbx-utils'
import { isNumber, isString } from 'lodash';

/** 
 * @description 连接器表单列表 转换为 项目内业务表单列表
*/
function connectorToFields2FormFields(toFields: ConnectorToField[]): ConnectorField[] {
  return toFields.map(connectorToField2FormField)
}

/** 
 * @description 连接器表单 转换为 项目内业务表单
*/
function connectorToField2FormField(toField?: ConnectorToField): ConnectorField {
  
  if (isFalsy(toField)) {
    return {} as ConnectorField
  }
  
  // 字段名称
  const fieldName = toField?.enName || ''
  // 字段类型
  const formType = toField?.fieldType
  // 字段显示名称
  const displayName = toField?.cnName
  // 是否支持高级搜索
  const isSearch = Number(toField?.supportSelect)
  // 是否显示
  const show = toField?.show
  
  // @ts-ignore
  const fixed = toField?.fixed
  
  let setting = toField?.setting || {}
  let isDateField = formType == FieldTypeMappingEnum.Date || formType == FieldTypeMappingEnum.DateTime
  
  if (isDateField && isFalsy(setting?.dateType)) {
    setting.dateType = DateFormatEnum.YTMHMS
  }
  
  return {
    fieldName,
    formType,
    displayName,
    isSearch,
    show,
    // @ts-ignore
    fixed,
    setting
  }
  
}

/**
 * @description 项目内业务表单列表 转换为 连接器表单列表
*/
function formFields2ConnectorFromFields(fields: Field[]): ConnectorField[] {
  return fields.map(formField2ConnectorFromField) as unknown as ConnectorField[]
}

/**
 * @description 项目内业务表单 转换为 连接器表单
*/
function formField2ConnectorFromField(field?: Field): ConnectorFromField {

  if (isFalsy(field)) {
    return {} as ConnectorFromField
  }

  // 字段名称
  const enName = field?.fieldName || ''
  // 字段类型
  const fieldType = field?.formType
  // 字段显示名称
  const cnName = field?.displayName
  // 字段是否显示
  const show = Boolean(field?.isShow)
  return {
    enName,
    fieldType,
    cnName,
    show
  }

}

/**
 * @description 连接器字段条件 是否为 置空
*/ 
function isConnectorRuleFormConditionEmpty(condition: ConnectorConditionTypeEnum): boolean {
  return condition == ConnectorConditionTypeEnum.Empty
}

/**
 * @description 连接器字段条件 是否为 固定值
*/ 
function isConnectorRuleFormConditionFixedValue(condition: ConnectorConditionTypeEnum): boolean {
  return condition == ConnectorConditionTypeEnum.FixedValue
}

/**
 * @description 连接器字段条件 是否为 对应字段
*/ 
function isConnectorRuleFormConditionFromField(condition: ConnectorConditionTypeEnum): boolean {
  return condition == ConnectorConditionTypeEnum.FromField
}

/**
 * @description 连接器字段条件 是否为 第三方应用表单字段
*/ 
function isConnectorRuleFormConditionAppFromField(condition: ConnectorConditionTypeEnum): boolean {
  return condition == ConnectorConditionTypeEnum.AppFormField
}

function sortConnectorToFieldsByShowFieldNameList(toFields: ConnectorToField[], showFieldNameList: string[]): ConnectorToField[] {
  
  const sortedToFields: ConnectorToField[] = []
  
  const originToFieldMap = toFields.reduce((prev, current) => {
    prev[current.enName] = current
    return prev
  }, {} as Record<string, ConnectorToField>)
  
  const showFieldNameListMap = showFieldNameList.reduce((prev, current) => {
    prev[current] = true
    return prev
  }, {} as Record<string, boolean>)
  
  let currentShowIndex: number = -1
  
  toFields.forEach(toField => {
    
    const isShow = showFieldNameListMap[toField.enName]
    
    if (isShow) {
      
      ++currentShowIndex
      
      const showFieldName = showFieldNameList[currentShowIndex]
      if(originToFieldMap[showFieldName]) {
        originToFieldMap[showFieldName].show = true
        sortedToFields.push(originToFieldMap[showFieldName])
      }
      
    } else {
      toField.show = false
      sortedToFields.push(toField)
        
    }
    
  })

  return sortedToFields
  
}

function getSortConnectorToFieldsByShowFieldNameList(toFields: ConnectorToField[], showFieldNameList: string[]): ConnectorToField[] {

  const sortedToFields: ConnectorToField[] = []

  const originToFieldMap = toFields.reduce((prev, current) => {
    prev[current.enName] = current
    return prev
  }, {} as Record<string, ConnectorToField>)

  const showFieldNameListMap = showFieldNameList.reduce((prev, current) => {
    prev[current] = true
    return prev
  }, {} as Record<string, boolean>)

  let currentShowIndex: number = -1

  toFields.forEach(toField => {

    const isShow = showFieldNameListMap[toField.enName]

    if (isShow) {

      ++currentShowIndex

      const showFieldName = showFieldNameList[currentShowIndex]

      sortedToFields.push(originToFieldMap[showFieldName])

    }

  })

  return sortedToFields

}

const matchRules:any = {
  'customer': ['customer', 'projectCustomer'],
  'text':['textarea','number','select','phone','email'],
  'textarea':['text','number','select','phone','email'],
  'number':['text','textarea','phone'],
  'phone':['text','textarea','number'],
  'email':['text','textarea']
}
// 支持固定值的formType
const supportedFormTypes = [
  'cascader', 'text','textarea','number','select','date','datetime','phone','email', 'select',
  'address','customer','linkman','product','related_customers','related_task','tags','user'
]

function matchFieldToTransform(tofield:ConnectorToField | any,fromField:ConnectorFromField):boolean{

  if((matchRules[tofield.fieldType] && matchRules[tofield.fieldType].indexOf(fromField.fieldType)>-1)||(tofield.fieldType === fromField.fieldType)){
    return true
  }

  return false
}
function isConnectorFixedValueMultiField(field: ConnectorToField | undefined): boolean {
  return [ConnectorFieldTypeEnum.RelatedCustomers, ConnectorFieldTypeEnum.Role].includes(field?.fieldType as ConnectorFieldTypeEnum)
}

function getShowFieldNameListByConnectorToFields(toFields: ConnectorToField[]): string[] {
  return toFields.filter(toField => toField?.show).map(toField => toField?.enName || '')
}

function containFieldType(fieldTypeList:Array<string>,fieldType:string){
  return fieldTypeList.indexOf(fieldType) > -1
}

function getFixedValue(item:any):string{
  if(!item.field) return t('common.connector.fixedValue')
  try {
    if(supportedFormTypes.indexOf(item.field?.fieldType)>-1){
      let fieldType = item.field?.fieldType || ''
      switch(true){
        // 多级菜单
        case containFieldType(['cascader'],fieldType):
          if (item?.value?.length && Array.isArray(item?.value)) {
            return item?.value.join('/')
          }
          return item?.value || ''
        case containFieldType(['text','textarea','number','phone','email', 'select'],fieldType):
          return item?.value || ''
        case containFieldType(['date','datetime'],fieldType):
          // 格式化时间戳显示
          const format = useFormTimezone().getFormDateFormat(fieldType)
          if (isNumber(item?.value) || isString(item?.value)){
            // 兼容晚于，早于的数据
            return formatDate(item?.value, format) as string
          }
          return `${formatDate(item?.value?.[0] || '', format)} ${t('common.base.to')} ${formatDate(item?.value?.[1] || '', format)}`
        case containFieldType(['address'],fieldType):
          return `${item?.value?.province || ''}${item?.value?.city ? ' / '+ item?.value?.city : '' }${item?.value?.dist ? ' / '+ item?.value?.dist : '' }`
        case containFieldType(['linkman','product','related_task','user'],fieldType):
          return item?.value?.name || item?.value?.taskNo || '';
          case containFieldType(['customer','related_customers'],fieldType):
            return item?.value?.[0]?.name || ''
      }
    }
    return t('common.connector.fixedValue')
  } catch (error) {
    console.error('固定值转换失败',item)
  }
  return t('common.connector.fixedValue')
}

function connectorOptionsExtraCompatibleHandler(connectorOptions: ConnectorOptions | ConnectorEditOptions, toBizType: ConnectorBizTypeEnum, toBizTypeId: string) {
  
  try {
    
    const toFieldList = connectorOptions?.toFieldList
    const insertFieldOptionsList = connectorOptions?.insertFieldOptionsList || []
    const selectFieldOptionsList = connectorOptions?.selectFieldOptionsList || []
    
    // 如果 to 是 客户表单时，需要将 联系人 字段处理成 单行文本
    // 触发器二期 判断是不是客户表单去掉 toBizTypeId = 1 判断
    if (toBizType == ConnectorBizTypeEnum.Customer) {
      
      toFieldList.forEach(field => {
        linkmanFieldChangeToTextField(field)
      })
      
      insertFieldOptionsList.forEach(option => {
        // 固定值特殊处理，需要转换
        if (option?.valueType == ConnectorOptionsFieldOptionValueTypeEnum.FixedValue) {
          linkmanFieldValueChangeToTextFieldValue(option)
        }
      })
      
      // 编辑附加组件联系人回显 
      selectFieldOptionsList.forEach(option => {
        // 固定值特殊处理，需要转换
        if (option?.valueType == ConnectorOptionsFieldOptionValueTypeEnum.FixedValue) {
          linkmanFieldValueChangeToTextFieldValue(option)
        }
      })
      
    }
    
  } catch (error) {
    
    Log.error(error, connectorOptionsExtraCompatibleHandler.name)
    
  }
  
}

function triggerLinesExtraCompatibleHandler(triggerLines: Record<string, any>[]) {
  try {

    // 如果 to 是 客户表单时，需要将 联系人 字段处理成 单行文本
    triggerLines.forEach(triggerLine => {

      const insertFieldOptions: ConnectorOptionsFieldOption[] = triggerLine?.executeAction?.insertFieldOptions || []
      
      const updateFieldOptions = triggerLine?.executeAction?.updateFieldOptions || {}
      const updateUpdateFieldOptions: ConnectorOptionsFieldOption[] = updateFieldOptions?.update || []
      const UpdateSelectFieldOptions: ConnectorOptionsFieldOption[] = updateFieldOptions?.select || []

      const allOptions = [...insertFieldOptions, ...updateUpdateFieldOptions, ...UpdateSelectFieldOptions]

      allOptions.forEach(field => {
        if (field?.valueType == ConnectorOptionsFieldOptionValueTypeEnum.FixedValue) {
          linkmanFieldValueChangeToTextFieldValue(field)
        }
      })

    })

  } catch (error) {

    Log.error(error, connectorOptionsExtraCompatibleHandler.name)

  }
}

function triggerActionAppExtraCompatibleHandler(actionAppFieldList: Record<string, any>[]) {
  try {

    // 如果 to 是 客户表单时，需要将 联系人 字段处理成 单行文本
    const fromFieldList: ConnectorOptionsFieldOption[] = actionAppFieldList?.fromFieldList || []
    const selectFieldList: ConnectorOptionsFieldOption[] = actionAppFieldList?.selectFieldList || []
    const toFieldList: ConnectorOptionsFieldOption[] = actionAppFieldList?.toFieldList || []

    const allOptions = [...fromFieldList, ...selectFieldList, ...toFieldList]

    allOptions.forEach(field => {
      if (field?.valueType == ConnectorOptionsFieldOptionValueTypeEnum.FixedValue) {
        linkmanFieldValueChangeToTextFieldValue(field)
      }
    })

  } catch (error) {

    Log.error(error, connectorOptionsExtraCompatibleHandler.name)

  }
}

function linkmanFieldChangeToTextField(field: ConnectorToField) {
  if (field?.fieldType == ConnectorFieldTypeEnum.Linkman) {
    field!.fieldType = ConnectorFieldTypeEnum.Text
  }
}

function linkmanTextFieldChangeToLinkmanField(field: ConnectorToField) {
  if (
    field?.fieldType == ConnectorFieldTypeEnum.Text
    && field?.enName == ConnectorFieldEnNameEnum.LinkmanName
  ) {
    field!.fieldType = ConnectorFieldTypeEnum.Linkman
  }
}

function linkmanFieldValueChangeToTextFieldValue(option: ConnectorOptionsFieldOption) {

  if (option?.toEnName == ConnectorFieldEnNameEnum.LinkmanName) {

    const value = option?.value?.[0] || ''
    const linkmanValue = parse(value)

    if (isObject(linkmanValue)) {
      option.value[0] = linkmanValue.name || ''
    }

  }

}

function getSupportedDisplayConnectorColumns(toFieldList: ConnectorToField[]): ConnectorToField[] {
  return toFieldList.filter(toField => toField?.enName != 'myself')
}

function connectorFromFieldsAddChildren(fromFields: ConnectorFromField[]) {

  if (isNotArray(fromFields)) {
    return
  }

  fromFields.forEach(fromField => {

    const fieldType = fromField?.fieldType

    fromField.children = ConnectorFieldTypeChildrenMap[fieldType] || []

  })

}

export {
  connectorToFields2FormFields,
  connectorToField2FormField,
  formFields2ConnectorFromFields,
  formField2ConnectorFromField,
  isConnectorRuleFormConditionEmpty,
  isConnectorRuleFormConditionFixedValue,
  isConnectorRuleFormConditionFromField,
  sortConnectorToFieldsByShowFieldNameList,
  matchFieldToTransform,
  getSortConnectorToFieldsByShowFieldNameList,
  isConnectorFixedValueMultiField,
  getShowFieldNameListByConnectorToFields,
  getFixedValue,
  connectorOptionsExtraCompatibleHandler,
  getSupportedDisplayConnectorColumns,
  connectorFromFieldsAddChildren,
  linkmanFieldChangeToTextField,
  triggerLinesExtraCompatibleHandler,
  triggerActionAppExtraCompatibleHandler,
  linkmanTextFieldChangeToLinkmanField,
  isConnectorRuleFormConditionAppFromField
}
